﻿using System;
using System.Globalization;
using System.Windows.Data;

namespace WDCF
{
    /// <summary>
    /// Converts numbers to boolean values
    /// </summary>
    public class NumberToBoolConverter : IValueConverter
    {
        /// <summary>
        /// Converts a numeric value to a boolean value. The compare value and a value of
        /// the <see cref="StringOperator"/> enumeration is extracted from the parameter
        /// object.
        /// </summary>
        /// <returns>
        /// A converted value according to the given operator value. 
        /// If the method returns null, the valid null value is used.
        /// </returns>
        /// <param name="value">The value produced by the binding source.</param>
        /// <param name="targetType">The type of the binding target property.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <exception cref="ArgumentException">If the parameters cannot be converted to a double value.</exception>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double v;
            if (double.TryParse(value.ToString(), out v))
            {
                string para = parameter.ToString();
                //operator and compare value are separated by |
                string[] split = para.Split(new[] {"|"}, StringSplitOptions.RemoveEmptyEntries);

                //for now any given number will be parsed to a double
                //if this does not succeed, an ArgumentException will be raised
                double p;
                if(double.TryParse(split[1], out p))
                {
                    NumericOperator numericOperator;
                    if (Enum.TryParse(split[0], true, out numericOperator))
                    {
                        switch (numericOperator)
                        {
                            case NumericOperator.None:
                                return false;
                            case NumericOperator.Equals:
                                return p == v;
                            case NumericOperator.GreaterThan:
                                return v > p;
                            case NumericOperator.SmallerThan:
                                return v < p;
                            case NumericOperator.GreaterThanEquals:
                                return v >= p;
                            case NumericOperator.SmallerThanEquals:
                                return v <= p;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                    }
                }
                else
                {
                    throw new ArgumentException(
                        string.Format("The given compare value ({0}) cannot be converted to double.", split[1]));
                }
            }
            else
            {
                throw new ArgumentException(string.Format("value ({0}) cannot be converted to double.", value), "value");
            }

            return false;
        }

        /// <summary>
        /// Converts a value. 
        /// </summary>
        /// <returns>
        /// A converted value. If the method returns null, the valid null value is used.
        /// </returns>
        /// <param name="value">The value that is produced by the binding target.</param>
        /// <param name="targetType">The type to convert to.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Converting values back is currently not supported.");
        }
    }
}
